package com.myBlast.data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import com.google.gwt.user.client.rpc.IsSerializable;

/**
 * Data Model for holding Blast results.
 * @author Parit Bansal
 */
@SuppressWarnings("serial")
public class BlastResult implements IsSerializable, Serializable {
	
	private Boolean doSyn = null; 
	/**
	 * The string containing project Settings
	 */
	private String projectSettings = null;
	
	/**
	 * The string containing the selectedTaxids
	 */
	private String selectedTaxes = null;
	
	/**
	 * The name of the organism.
	 */
	private String organismName = null;
	
	/**
	 * The tax id of the organism
	 */
	private int organismId;
	
	/**
	 * max eval associated with this hit
	 */
	private double maxEVal;
	
	/**
	 * min e-val associated with this hit.
	 */
	private double minEVal;
	
	/**
	 * 
	 */
	private double maxBitScore;
	
	/**
	 * 
	 */
	private double minBitScore;
	
	/**
	 * 
	 */
	private String maxBitScoreHitIdentifier = null;
	
	/**
	 * 
	 */
	private String minBitScoreHitIdentifier = null;
	
	/**
	 * 
	 */
	private String maxEValHitIdentifier;
	
	/**
	 * 
	 */
	private String minEValHitIdentifier;
	
	private String fileExtension = null;
	
	public String getFileExtension() {
		return fileExtension;
	}

	public void setFileExtension(String fileExtension) {
		this.fileExtension = fileExtension;
	}

	/**
	 * 
	 */
	private String errorMessage = null;
	
	public Boolean getDoSyn() {
		return doSyn;
	}

	public BlastResult setDoSyn(Boolean doSyn) {
		this.doSyn = doSyn;
		return this;
	}

	public String getErrorMessage() {
		return errorMessage;
	}

	public BlastResult setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
		return this;
	}

	public String getSelectedTaxes() {
		return selectedTaxes;
	}

	public BlastResult setSelectedTaxes(String selectedTaxes) {
		this.selectedTaxes = selectedTaxes;
		return this;
	}

	public String getProjectSettings() {
		return projectSettings;
	}
	
	public BlastResult setProjectSettings(String projectSettings) {
		this.projectSettings = projectSettings;
		return this;
	}
	
	public String getMaxBitScoreHitIdentifier() {
		return maxBitScoreHitIdentifier;
	}
	public BlastResult setMaxBitScoreHitIdentifier(String maxBitScoreHitIdentifier) {
		this.maxBitScoreHitIdentifier = maxBitScoreHitIdentifier;
		return this;
	}
	public String getMinBitScoreHitIdentifier() {
		return minBitScoreHitIdentifier;
	}
	public BlastResult setMinBitScoreHitIdentifier(String minBitScoreHitIdentifier) {
		this.minBitScoreHitIdentifier = minBitScoreHitIdentifier;
		return this;
	}
	public String getMaxEValHitIdentifier() {
		return maxEValHitIdentifier;
	}
	public BlastResult setMaxEValHitIdentifier(String maxEValHitIdentifier) {
		this.maxEValHitIdentifier = maxEValHitIdentifier;
		return this;
	}
	public String getMinEValHitIdentifier() {
		return minEValHitIdentifier;
	}
	public BlastResult setMinEValHitIdentifier(String minEValHitIdentifier) {
		this.minEValHitIdentifier = minEValHitIdentifier;
		return this;
	}
	public static Comparator<BlastResult> getEvalComparator() {
		return evalComparator;
	}
	public static void setEvalComparator(Comparator<BlastResult> evalComparator) {
		BlastResult.evalComparator = evalComparator;
	}
	public static Comparator<BlastResult> getBitScoreComparator() {
		return bitScoreComparator;
	}
	public static void setBitScoreComparator(
			Comparator<BlastResult> bitScoreComparator) {
		BlastResult.bitScoreComparator = bitScoreComparator;
	}
	
	/**
	 * This will contain the list of hitNames in the following order.
	 * 1. hit corresponding to maxBit Score
	 * 2. hit corresponding to minBit Score
	 * 3. hit corresponding to max E-Val
	 * 4. hit corresponding to min E-Val 
	 */
	private List<String> hitIdentifier = null;
	
	public double getMaxBitScore() {
		return maxBitScore;
	}
	public BlastResult setMaxBitScore(double maxBitScore) {
		this.maxBitScore = maxBitScore;
		return this;
	}
	public double getMinBitScore() {
		return minBitScore;
	}
	public BlastResult setMinBitScore(double minBitScore) {
		this.minBitScore = minBitScore;
		return this;
	}
	public List<String> getHitIdentifier() {
		return hitIdentifier;
	}
	public BlastResult setHitIdentifier(List<String> hitIdentifier) {
		this.hitIdentifier = hitIdentifier;
		return this;
	}
	public String getOrganismName() {
		return organismName;
	}
	public BlastResult setOrganismName(String organismName) {
		this.organismName = organismName;
		return this;
	}
	public int getOrganismId() {
		return organismId;
	}
	public BlastResult setOrganismId(int organismId) {
		this.organismId = organismId;
		return this;
	}
	public double getMaxEVal() {
		return maxEVal;
	}
	public BlastResult setMaxEVal(double maxEVal) {
		this.maxEVal = maxEVal;
		return this;
	}
	public double getMinEVal() {
		return minEVal;
	}
	public BlastResult setMinEVal(double minEVal) {
		this.minEVal = minEVal;
		return this;
	}
	
	/**
	 * A utility method to create a dummy list of BlastResult
	 * objects for debugging purposes. 
	 * This has not been made part of StaticData class because
	 * StaticData is converted into JS and we dont want this method
	 * to go in there.
	 * @return a list of BlastResult objects
	 */
	public static ArrayList<BlastResult> getStaticData()
	{
		ArrayList<BlastResult> list = new ArrayList<BlastResult>();
		BlastResult blastResultModel = new BlastResult();
		blastResultModel.setMaxEVal(5.3).setMinEVal(1.2).setOrganismName("human7").setOrganismId(9606);
		list.add(blastResultModel);
		
		BlastResult blastResultModel1 = new BlastResult();
		blastResultModel1.setMaxEVal(5.4).setMinEVal(1.7).setOrganismName("human6").setOrganismId(9607);
		list.add(blastResultModel1);

		BlastResult blastResultModel2 = new BlastResult();
		blastResultModel2.setMaxEVal(5.5).setMinEVal(1.6).setOrganismName("human5").setOrganismId(9608);
		list.add(blastResultModel2);
		
		BlastResult blastResultModel3 = new BlastResult();
		blastResultModel3.setMaxEVal(5.6).setMinEVal(1.5).setOrganismName("human4").setOrganismId(9609);
		list.add(blastResultModel3);
		
		BlastResult blastResultModel4 = new BlastResult();
		blastResultModel4.setMaxEVal(5.7).setMinEVal(1.4).setOrganismName("human3").setOrganismId(9610);
		list.add(blastResultModel4);
		
		BlastResult blastResultModel5= new BlastResult();
		blastResultModel5.setMaxEVal(5.9).setMinEVal(1.3).setOrganismName("human2").setOrganismId(9611);
		list.add(blastResultModel5);
		
		BlastResult blastResultModel6 = new BlastResult();
		blastResultModel6.setMaxEVal(5.8).setMinEVal(1.2).setOrganismName("human1").setOrganismId(9612);
		list.add(blastResultModel6);

		return list;
	}
	
	public static Comparator<BlastResult> evalComparator = new Comparator<BlastResult>() {
		
		@Override
		public int compare(BlastResult o1, BlastResult o2) {
			double eval1 = o1.getMaxEVal();
			double eval2 = o2.getMaxEVal();
			return Double.compare(eval1, eval2);
		}
	};
	
	
	public static Comparator<BlastResult> bitScoreComparator = new Comparator<BlastResult>() {
		
		@Override
		public int compare(BlastResult o1, BlastResult o2) {
			double bitScore1 = o1.getMaxBitScore();
			double bitScore2 = o2.getMaxBitScore();
			return Double.compare(bitScore1, bitScore2);
		}
	};
}// BlastResultModel
